package cn.iocoder.yudao.module.pay.wechat.dao;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.business.basic.dao.mapper.CoreMapper;
import cn.iocoder.yudao.framework.business.basic.dao.query.CoreLambdaQueryWrapper;
import cn.iocoder.yudao.module.api.infrastructure.wechat.vo.WechatOrderDetailVO;
import cn.iocoder.yudao.module.api.pay.splitting.enums.MallBookSplitStatusEnum;
import cn.iocoder.yudao.module.api.pay.wechat.enums.WechatOrderStatusEnum;
import cn.iocoder.yudao.module.pay.splitting.pojo.bo.PaySplittingBO;
import cn.iocoder.yudao.module.pay.wechat.convert.WechatOrderInfoConvert;
import cn.iocoder.yudao.module.pay.wechat.pojo.po.WechatOrderInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <pre>
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 * Mapper 接口
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 * </pre>
 *
 * @author 山野羡民（1032694760@qq.com）
 * @since 2025/07/22
 */
@Mapper
public interface WechatOrderInfoMapper extends CoreMapper<WechatOrderInfo> {

    default List<String> selectPayNoByCompleted(LocalDateTime minDateTime) {
        List<WechatOrderInfo> list = selectList(new LambdaQueryWrapper<WechatOrderInfo>()
                .select(WechatOrderInfo::getPayNo)
                .in(WechatOrderInfo::getOrderState, List.of(WechatOrderStatusEnum.COMPLETED.getValue(), WechatOrderStatusEnum.REFUNDED.getValue(), WechatOrderStatusEnum.SETTLEMENT.getValue(), WechatOrderStatusEnum.ERROR.getValue()))
                .ge(WechatOrderInfo::getCreateTime, minDateTime));
        if (CollUtil.isEmpty(list)) {
            return List.of();
        }
        return list.stream().map(WechatOrderInfo::getPayNo).toList();
    }

    default List<String> selectPayNoByPaid(LocalDateTime minDateTime) {
        List<WechatOrderInfo> list = selectList(new LambdaQueryWrapper<WechatOrderInfo>()
                .select(WechatOrderInfo::getPayNo)
                .eq(WechatOrderInfo::getOrderState, WechatOrderStatusEnum.PAID.getValue())
                .ge(WechatOrderInfo::getCreateTime, minDateTime));
        if (CollUtil.isEmpty(list)) {
            return List.of();
        }
        return list.stream().map(WechatOrderInfo::getPayNo).toList();
    }

    default List<PaySplittingBO> selectByMinDateTimeAndCanSplitting(LocalDateTime minDateTime) {
        List<WechatOrderInfo> list = selectList(new LambdaQueryWrapper<WechatOrderInfo>()
                .select(WechatOrderInfo::getPayNo, WechatOrderInfo::getPaidAmount)
                .in(WechatOrderInfo::getOrderState, List.of(WechatOrderStatusEnum.COMPLETED.getValue(), WechatOrderStatusEnum.SETTLEMENT.getValue()))
                .in(WechatOrderInfo::getSplitStatus, List.of(MallBookSplitStatusEnum.WAIT.getValue(), MallBookSplitStatusEnum.FAILURE.getValue()))
                .ge(WechatOrderInfo::getCreateTime, minDateTime));
        if (CollUtil.isEmpty(list)) {
            return List.of();
        }
        return list.stream().map(WechatOrderInfoConvert.INSTANCE::convert).toList();
    }

    default void saveResult(String payNo, WechatOrderDetailVO result) {
        CoreLambdaQueryWrapper<WechatOrderInfo> wrapper = new CoreLambdaQueryWrapper<>();
        wrapper.eq(WechatOrderInfo::getPayNo, payNo);
        WechatOrderInfo shipping = selectOne(wrapper);
        if (shipping == null) {
            shipping = WechatOrderInfoConvert.INSTANCE.convert(payNo, result);
            shipping.setSplitStatus(MallBookSplitStatusEnum.WAIT.getValue());
            insert(shipping);
        } else {
            WechatOrderInfo updateObj = WechatOrderInfoConvert.INSTANCE.convert(payNo, result);
            updateObj.setId(shipping.getId());
            updateById(updateObj);
        }
    }

    default void updateSplitStatus(String payNo, Integer status, String errorMsg) {
        LambdaUpdateWrapper<WechatOrderInfo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(WechatOrderInfo::getPayNo, payNo);
        WechatOrderInfo updateObj = new WechatOrderInfo();
        updateObj.setSplitStatus(status);
        updateObj.setErrorMsg(errorMsg);
        update(updateObj, updateWrapper);
    }

}
